package hn.sigit.model.hnd.ladmshadow;

import hn.sigit.model.commons.ISpatialZone;
import hn.sigit.model.hnd.cadastre.HND_LandUse;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.Type;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;

@Entity
@org.hibernate.annotations.Proxy(lazy=false)
@Table(name="SpatialZone", schema="ladmshadow")
@Inheritance(strategy=InheritanceType.JOINED)
@PrimaryKeyJoinColumn(name="SpatialUnitID", referencedColumnName="ID")
public class SpatialZone extends SpatialUnit implements Serializable, Cloneable, ISpatialZone {
	private static final long serialVersionUID = 1L;

	public SpatialZone() {
	}

	private Geometry shape;
	private String zoneName;
	private String locationInCountry;
	private BigDecimal geometryPerimeter;
	private BigDecimal measuredPerimeter;
	private BigDecimal documentedPerimeter;
	private BigDecimal geometryArea;
	private BigDecimal measuredArea;
	private BigDecimal documentedArea;

	private HND_LandUse currentLandUse;
	private HND_LandUse proposedLandUse;


	@Column(name="Shape", nullable=false)
	@Type(type = "org.hibernatespatial.GeometryUserType")
	public Geometry getShape() {
		return shape;
	}
	public void setShape(Geometry value) {
		if (this.shape == null || !this.shape.equalsExact(value)) {
			this.shape = value;
			
			Point newRefPoint = value.getCentroid();
			newRefPoint.setSRID(value.getSRID());
			this.setReferencePoint(newRefPoint);
		}
	}
	
	@Column(name="ZoneName", nullable=true)
	public String getZoneName() {
		return zoneName;
	}
	public void setZoneName(String zoneName) {
		this.zoneName = zoneName;
	}
	
	@Column(name="LocationInCountry", nullable=true)
	public String getLocationInCountry() {
		return locationInCountry;
	}
	public void setLocationInCountry(String locationInCountry) {
		this.locationInCountry = locationInCountry;
	}
	
	@Column(name="GeometryPerimeter", nullable=true, precision=16, scale=8)
	public BigDecimal getGeometryPerimeter() {
		return geometryPerimeter;
	}
	public void setGeometryPerimeter(BigDecimal geometryPerimeter) {
		this.geometryPerimeter = geometryPerimeter;
	}
	
	@Column(name="MeasuredPerimeter", nullable=true, precision=16, scale=8)
	public BigDecimal getMeasuredPerimeter() {
		return measuredPerimeter;
	}
	public void setMeasuredPerimeter(BigDecimal measuredPerimeter) {
		this.measuredPerimeter = measuredPerimeter;
	}
	
	@Column(name="DocumentedPerimeter", nullable=true, precision=16, scale=8)
	public BigDecimal getDocumentedPerimeter() {
		return documentedPerimeter;
	}
	public void setDocumentedPerimeter(BigDecimal documentedPerimeter) {
		this.documentedPerimeter = documentedPerimeter;
	}
	
	@Column(name="GeometryArea", nullable=true, precision=16, scale=8)
	public BigDecimal getGeometryArea() {
		return geometryArea;
	}
	public void setGeometryArea(BigDecimal geometryArea) {
		this.geometryArea = geometryArea;
	}
	
	@Column(name="DocumentedArea", nullable=true, precision=16, scale=8)
	public BigDecimal getDocumentedArea() {
		return documentedArea;
	}
	public void setDocumentedArea(BigDecimal documentedArea) {
		this.documentedArea = documentedArea;
	}
	
	@Column(name="MeasuredArea", nullable=true, precision=16, scale=8)
	public BigDecimal getMeasuredArea() {
		return measuredArea;
	}
	public void setMeasuredArea(BigDecimal measuredArea) {
		this.measuredArea = measuredArea;
	}
	
	@OneToOne(targetEntity=HND_LandUse.class, fetch=FetchType.LAZY)
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
	@JoinColumns({ @JoinColumn(name="CurrentLandUseID") })
	@org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.NO_PROXY)
	public HND_LandUse getCurrentLandUse() {
		return currentLandUse;
	}
	public void setCurrentLandUse(HND_LandUse currentLandUse) {
		this.currentLandUse = currentLandUse;
	}
	
	@OneToOne(targetEntity=HND_LandUse.class, fetch=FetchType.LAZY)
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
	@JoinColumns({ @JoinColumn(name="ProposedLandUseID") })
	@org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.NO_PROXY)
	public HND_LandUse getProposedLandUse() {
		return proposedLandUse;
	}
	public void setProposedLandUse(HND_LandUse proposedLandUse) {
		this.proposedLandUse = proposedLandUse;
	}

	
	@Transient
	public Property getProperty() {
		Property prop = null;
		Set<BAUnit> baUnitSet = super.getBaunits();
		for (BAUnit baUnit : baUnitSet) {
			if (baUnit instanceof Property) {
				prop = (Property)baUnit;
				break;
			}
		}
		return prop;
	}
}
